package com.hongxing.baseaar.base

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType

abstract class BaseXAdapter<T, VB : ViewBinding>(
    var items: MutableList<T> = arrayListOf()
) : RecyclerView.Adapter<BaseXAdapter.ViewBindingHolder<VB>>() {
    var bindingHolder: ViewBindingHolder<VB>? = null
    private var onItemClickListener: ((T, Int) -> Unit)? = null
    private val inflateMethod by lazy {
        ((javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<*>).getMethod(
            "inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java
        ).apply {
            isAccessible = true
        }
    }

    @Suppress("UNCHECKED_CAST")
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewBindingHolder<VB> {
        bindingHolder = ViewBindingHolder(
            inflateMethod.invoke(
                null, LayoutInflater.from(parent.context), parent, false
            ) as VB
        )
        return bindingHolder ?: ViewBindingHolder(
            inflateMethod.invoke(
                null, LayoutInflater.from(parent.context), parent, false
            ) as VB
        )
    }


    override fun getItemCount() = items.size
    override fun onBindViewHolder(holder: ViewBindingHolder<VB>, position: Int) {
        bindData(holder.binding, items[position], position)
        holder.itemView.setOnClickListener {
            onItemClickListener?.invoke(items[position], position)
        }
    }

    fun setOnItemClickListener(onItemClickListener: (bean: T, position: Int) -> Unit) {
        this.onItemClickListener = onItemClickListener
    }

    abstract fun bindData(binding: VB, bean: T, position: Int)

    fun isEmpty() = items.isEmpty()


    open fun add(item: T) {
        items.add(item)
        notifyItemChanged(items.size - 1)
    }

    open fun addInsertPosition(item: T, position: Int) {
        items.add(position, item)
        notifyItemInserted(position)
        notifyItemRangeChanged(position + 1, items.size)
    }

    @SuppressLint("NotifyDataSetChanged")
    open fun addAll(items: List<T>) {
        this.items.addAll(items)
        notifyDataSetChanged()
    }

    @SuppressLint("NotifyDataSetChanged")
    fun setList(list: MutableList<T>) {
        items = list
        notifyDataSetChanged()
    }

    fun remove(index: Int) {
        items.removeAt(index)
        notifyItemRemoved(index)
        notifyItemRangeChanged(index, items.size)
    }

    private val mLock = Any()

    fun removeChangedPart(index: Int) {
        synchronized(mLock) {
            items.removeAt(index)
            notifyItemRemoved(index)
            notifyItemRangeChanged(index, items.size)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    fun clear() {
        items.clear()
        notifyDataSetChanged()
    }

    class ViewBindingHolder<VB : ViewBinding>(val binding: VB) :
        RecyclerView.ViewHolder(binding.root)
}